package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.annotation.Arithmetic;
import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.var.VarRotationLow;
import com.navinfo.platform.trip.common.arithmetic.enums.EventStatus;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;

import java.util.Optional;

/**
 * 引擎低转速相关算法(脱档)<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 */
@Arithmetic(name = "引擎低转速算法")
public class RotationLow extends AbstractArithmetic<VarRotationLow> {
    /**
     * 事件类型
     */
    private EventType eventType = EventType.engineLowSpeed;
    /**
     * 转速阀值 单位:RPM
     */
    private int rotationThreshold = ConfigMap.getInteger("LowRotation_rotation_threshold");
    /**
     * 油门开合度阀值 单位: 0-100
     */
    private int accThreshold = ConfigMap.getInteger("LowRotation_acc_threshold");

    /**
     * 判断当前点是否低转速
     */
    private boolean isLowRotation() {
        CommonData commonData = getCommonData();
        //油门大于10、转速低于1000（大马力机型为转速低于900）,现在没有判断发动机型号是否为大马力机型，都用1000
        return (commonData.getAcceleratorPosition()>accThreshold) && (commonData.getRotation()<rotationThreshold);
    }

    @Override
    public void calculate() {
        logger.debug("===============引擎低转速算法开始===========");
        VarRotationLow var = getObj();
        boolean preState= var.isPreState();
        boolean curState= isLowRotation();
        logger.debug("进入引擎低转速算法，前一点状态：{}，当前点状态：{}，[terminalId:{}]", preState, curState, terminalId);

        EventStatus eventStatus = getEventStatus(var.isPreState(), isLowRotation());
        switch (eventStatus) {
            case START:
                logger.debug("引擎低转速算法，事件开始.[terminalId:{}]", terminalId);
                startEventData(eventType);
                break;
            case IN:
                logger.debug("引擎低转速算法，事件中.[terminalId:{}]", terminalId);
                calcEventData(eventType);
                break;
            case END:
                logger.debug("引擎低转速算法，事件结束.[terminalId:{}]", terminalId);
                calcEventData(eventType);
                endEventData();
                break;
            default:
                logger.debug("引擎低转速算法：上一次和本次都引擎低转速，跳出算法.[terminalId:{}]", terminalId);
        }

        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEventData();
        }

        //更新上一个点的状态，供下个点使用
        var.setPreState(curState);
        logger.debug("===============引擎低转速算法结束===========");
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarRotationLow var = getObj();
        statisticDataOut.setLrogNumber(var.getNumber());
        statisticDataOut.setLrogMileage(ArithmeticUtils.mileageMToM(var.getMileage()));
        statisticDataOut.setLrogFuel(ArithmeticUtils.fuelMlToMl(var.getFuel()));
        statisticDataOut.setLrogDuration(ArithmeticUtils.timeMsToSecond(var.getDuration()));
    }

    private void endEventData(){
        endEventData(eventType, eventData -> {
            VarRotationLow varRotationLow = getObj();
            varRotationLow.addNumber( 1);
            varRotationLow.addMileage( Optional.ofNullable(eventData.getExtendField05()).orElse(0.0));
            varRotationLow.addFuel( Optional.ofNullable(eventData.getExtendField06()).orElse(0.0).intValue());
            varRotationLow.addDuration( Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());
        });
    }
}
